package com.dingdang.sms.allinone.sender.impl

import com.alibaba.fastjson.JSON
import com.aliyuncs.DefaultAcsClient
import com.aliyuncs.dyvmsapi.model.v20170525.SingleCallByTtsRequest
import com.aliyuncs.profile.DefaultProfile
import com.dingdang.sms.allinone.config.AllInOneConfigurationProperties
import com.dingdang.sms.allinone.sender.AllInOneSender
import com.dingdang.sms.allinone.sender.ResultWrapper
import com.dingdang.sms.allinone.sender.Target

class AliyunVmsSender(val properties: AllInOneConfigurationProperties) : AllInOneSender {

    private val product by lazy { "Dyvmsapi" }

    private val domain by lazy { "dyvmsapi.aliyuncs.com" }

    private val profile by lazy { prepareProfile() }

    private fun prepareProfile(): DefaultProfile {
        val profile = DefaultProfile.getProfile(
            properties.aliyun?.vms?.regionId,
            properties.aliyun?.vms?.accessId,
            properties.aliyun?.vms?.accessSecret
        )
        DefaultProfile.addEndpoint(
            properties.aliyun?.vms?.endpoint,
            properties.aliyun?.vms?.regionId,
            product, domain
        )
        return profile
    }

    private val acsClient by lazy { DefaultAcsClient(profile) }

    override fun send(target: Target, block: (ResultWrapper) -> Unit) {
        val result = send(target)
        block(result)
    }

    override fun send(target: Target): ResultWrapper {
        target.checkTemplateId()
        target.checkVoiceNumber()
        return if (target.isSingleTarget()) {
            sendSingleCall(target)
        } else {
            sendMultiCall(target)
        }
    }


    private fun sendSingleCall(target: Target): ResultWrapper {
        return executeRequest(target.voiceNumber, target.templateId, target.params, target.mobileList!!.first())
    }

    private fun sendMultiCall(target: Target): ResultWrapper {
        val ret = ResultWrapper()
        val resultList = mutableListOf<ResultWrapper>()
        target.mobileList?.forEach {
            val result = executeRequest(target.voiceNumber, target.templateId, target.params, it)
            resultList.add(result)
        }
        return if (resultList.isEmpty()) {
            ret.ok()
        } else {
            ret.error(data = resultList)
        }
    }

    private fun executeRequest(
        calledNumber: String?,
        templateId: String?,
        params: Map<String, String>?,
        mobile: String
    ): ResultWrapper {
        val request = SingleCallByTtsRequest()
        request.calledShowNumber = calledNumber
        request.ttsCode = templateId
        request.calledNumber = mobile
        request.ttsParam = JSON.toJSONString(params)
        request.volume = properties.aliyun?.vms?.volume
        request.playTimes = properties.aliyun?.vms?.playTimes
        val response = acsClient.getAcsResponse(request)
        return if (response.code == null || response.code != "OK") {
            ResultWrapper().error(message = "语音发送失败，目标电话${mobile},失败原因${response.message}")
        } else {
            ResultWrapper().ok(message = "语音发送成功，目标电话${mobile}")
        }
    }

}